package com.demo.base.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * 分页查询输出值
 * Created by ethan on 2017/1/13.
 */
public class PagedOutput<T> extends BaseOutput {

    /**
     * 每页显示数量
     */
    private int size;

    /**
     * 当前页码
     */
    private int page;

    /**
     * 是否有下一页
     */
    private int next;

    /**
     * 总页数
     */
    private long totalPages;

    /**
     * 总条数
     */
    private long totalElements;

    /**
     * 内容
     */
    private List<T> list;

    public PagedOutput() {
        this(new PagedInput(), 0, null);
    }

    public PagedOutput(PagedInput input, long totalElements, List<T> list) {
        this(CommonStatus.OK, input, totalElements, list);
    }

    public PagedOutput(String message, PagedInput input, long totalElements, List<T> list) {
        this(CommonStatus.OK.getCode(), message, input, totalElements, list);
    }

    public PagedOutput(OutputStatus status, PagedInput input, long totalElements, List<T> list) {
        this(status.getCode(), status.getMessage(), input, totalElements, list);
    }

    public PagedOutput(String status, String message, PagedInput input, long totalElements, List<T> list) {
        super(status, message);
        this.size = input.getSize();
        this.page = input.getPage();
        this.totalElements = totalElements;
        this.totalPages = (long) Math.ceil(((double) totalElements) / input.getSize());
        this.list = list;
        this.next = (totalPages <= this.page) ? 0 : 1;
    }

    public PagedOutput(int size, int page, long totalElements, List<T> list) {
        this.size = size;
        this.page = page;
        this.list = list;
        this.totalElements = totalElements;
        this.totalPages = (long) Math.ceil(((double) totalElements) / size);

        this.next = (totalPages <= this.page) ? 0 : 1;
    }


    public PagedOutput(int size, int page, long totalPages, long totalElements, List<T> list) {
        this.size = size;
        this.page = page;
        this.totalPages = totalPages;
        this.totalElements = totalElements;
        this.list = list;

        this.next = (totalPages <= this.page) ? 0 : 1;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getNext() {
        return next;
    }

    public void setNext(int next) {
        this.next = next;
    }

    public long getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(long totalPages) {
        this.totalPages = totalPages;
    }

    public long getTotalElements() {
        return totalElements;
    }

    public void setTotalElements(long totalElements) {
        this.totalElements = totalElements;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public <R extends Serializable> PagedOutput<R> map(Function<T, R> converter) {
        List<R> list = new ArrayList<>();
        for (T item : this.list) {
            R value = converter.apply(item);
            list.add(value);
        }
        return new PagedOutput<R>(
                this.size, this.page,
                this.totalPages, this.totalElements,
                list
        );
    }
}
